package org.swingplus.core.utils;

import org.swingplus.core.annotation.Autowired;
import org.swingplus.core.bean.DefinitionMetadata;
import org.swingplus.core.constant.bean.DependentOn;
import org.swingplus.core.util.AnnoManageUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class ClassFileInfoParseUtil {









	/**
     * 获取类的基本信息
     *
     * @param clazz
     * @return
     */
    public static DefinitionMetadata getDefinitionMetadata(Class clazz) {
        DefinitionMetadata definitionMetadata = new DefinitionMetadata();
        definitionMetadata.setInstance(null);
        definitionMetadata.setBeanClass(clazz);
        Field[] fields = clazz.getFields();
        definitionMetadata.setFields(fields);
        definitionMetadata.setFieldSize(fields.length);

        Field[] declaredFields = clazz.getDeclaredFields();
        definitionMetadata.setDeclaredFields(declaredFields);
        Field[] autowiredFields = getAutowiredFields(declaredFields);
        definitionMetadata.setAutowiredField(autowiredFields);
        if(autowiredFields.length>0){
            definitionMetadata.setExistsAutowired(true);
        }else{
            definitionMetadata.setExistsAutowired(false);
        }
        Method[] methods = clazz.getMethods();
        definitionMetadata.setMethods(methods);
        definitionMetadata.setMethodSize(methods.length);

        boolean flag = AnnoManageUtil.existAutowiredConstructors(clazz);
        if (flag) {
            definitionMetadata.setDependentOn(DependentOn.CONSTRUCTOR.toString());
        } else {
            definitionMetadata.setDependentOn(DependentOn.SETTTER.toString());
        }






        return definitionMetadata;

    }
	
	
	
	
    /**
     * 获取类的基本信息
     *
     * @param clazz
     * @return
     */
    public static DefinitionMetadata getDefinitionMetadata(Class clazz, Object instance) {
        DefinitionMetadata definitionMetadata = new DefinitionMetadata();
        definitionMetadata.setInstance(instance);
        Field[] fields = clazz.getFields();
        definitionMetadata.setFields(fields);
        definitionMetadata.setFieldSize(fields.length);
        Field[] declaredFields = clazz.getDeclaredFields();
        definitionMetadata.setDeclaredFields(declaredFields);
        Field[] autowiredFields = getAutowiredFields(declaredFields);
        definitionMetadata.setAutowiredField(autowiredFields);
        if(autowiredFields.length>0){
            definitionMetadata.setExistsAutowired(true);
        }else{
            definitionMetadata.setExistsAutowired(false);
        }
        Method[] methods = clazz.getMethods();
        definitionMetadata.setMethods(methods);
        definitionMetadata.setMethodSize(methods.length);
//        SETTTER
        boolean flag=AnnoManageUtil.existAutowiredConstructors(clazz);
       if(flag) {
    	   definitionMetadata.setDependentOn(DependentOn.CONSTRUCTOR.toString());
       }else {
    	   definitionMetadata.setDependentOn(DependentOn.SETTTER.toString());
       }

       return definitionMetadata;

    }

    public static DefinitionMetadata getDefinitionMetadata(Object obj) {
        return getDefinitionMetadata(obj.getClass(), obj);
    }


    /**
     * 获取类中成员变量上有Autowired注解字段
     *
     * @param fields
     * @return
     */
    public static String[] getAutowiredByBeanName(Field[] fields) {

        Field[] field = getAutowiredFields(fields);

        String[] string=new String[field.length];
        for (int i = 0; i < field.length; i++) {
            string[i] =field[i].getName();
        }

        return string;
    }


    /**
     * 获取类中成员变量上有Autowired注解字段
     *
     * @param fields
     * @return
     */
    public static Field[] getAutowiredFields(Field[] fields) {
        List<Field> fieldsList = new ArrayList<>();
        for (Field field : fields) {
            if (isAutowiredField(field)) {
                fieldsList.add(field);
            }
            ;
        }
        Field[] fieldArray = new Field[fieldsList.size()];
        return fieldsList.toArray(fieldArray);
    }

    /**
     * 判断类中成员变量上有Autowired注解字段
     *
     * @param field
     * @return
     */
    public static boolean isAutowiredField(Field field) {
        Autowired autowired = field.getAnnotation(Autowired.class);
        if (null != autowired) {
            return true;
        }
        return false;
    }

}
